﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using System.Data;
using JXT.PrimaryKey.Batman.Extensions;
using JXT.PrimaryKey.Batman.Domain.Models;
using JXT.PrimaryKey.Batman.Domain.Specifications;
using JXT.PrimaryKey.Batman.Domain.UserSystem.Models;
using JXT.PrimaryKey.Batman.Domain.UserSystem.Repositories;
using JXT.PrimaryKey.Batman.Domain.Repositories.SqlServer.Expressions;

namespace JXT.PrimaryKey.Batman.Domain.Repositories.SqlServer.UserSystem
{
    public class SqlUserRepository : SqlServerRepositoryBase<User, int>, IUserRepository
    {
        public SqlUserRepository(RepositoryContext context)
            : base((SqlServerRepositoryContext)context)
        {
        }

        public override void Add(User entity)
        {
            base.Add(entity);
        }

        public UserDetail GetDetail(int userId)
        {
            string sql = "select * from [userdetail] where [userid]=" + userId;
            UserDetail result = null;
            using (var dr = Context.ExecuteDataReader(sql))
            {
                if (dr.Read())
                {
                    result = ReadFromDataReader<UserDetail>(dr);
                }
            }
            return result;
        }

        public UserStatus GetStatus(int userId)
        {
            string sql = "select * from [userstatus] where [userid]=" + userId;
            UserStatus result = null;
            using (var dr = Context.ExecuteDataReader(sql))
            {
                if (dr.Read())
                {
                    result = ReadFromDataReader<UserStatus>(dr);
                }
            }
            return result;
        }

        public void AddDetail(UserDetail detail)
        {
            InsertQuery query = new InsertQuery();
            query.Append(detail);
            Context.ExecuteNonQuery(query.QueryText, query.Parameters);
        }

        public void AddStatus(UserStatus status)
        {
            InsertQuery query = new InsertQuery();
            query.Append(status);
            Context.ExecuteNonQuery(query.QueryText, query.Parameters);
        }

        public void UpdateDetail(UserDetail detail)
        {
            UpdateQuery query = new UpdateQuery("userid");
            query.Append(detail);
            Context.ExecuteNonQuery(query.QueryText, query.Parameters);
        }

        public void UpdateStatus(UserStatus status)
        {
            UpdateQuery query = new UpdateQuery("userid");
            query.Append(status);
            Context.ExecuteNonQuery(query.QueryText, query.Parameters);
        }

        public void DeleteDetail(int userId)
        {
            string sql = "delete from [userdetail] where [userid]=" + userId;
            Context.ExecuteNonQuery(sql);
        }

        public void DeleteStatus(int userId)
        {
            string sql = "delete from [userstatus] where [userid]=" + userId;
            Context.ExecuteNonQuery(sql);
        }

        public int[] GetRoleIdArray(int userId)
        {
            string sql = "select * from [userrole] where [userid]=" + userId;
            List<int> roleIdList = new List<int>();
            using (var dr = Context.ExecuteDataReader(sql))
            {
                while (dr.Read())
                {
                    int id = dr.Read<int>("roleid");
                    if (id > 0)
                        roleIdList.Add(id);
                }
            }
            return roleIdList.ToArray();
        }

        public void SetAuthority(int userId, Authority[] authorityArray)
        {
            string authorityString = authorityArray.ToJsonString();
            string sql = "update [user] set [authority]=@authority where [id]=@id";
            Context.ExecuteNonQuery(sql, new[]{
                Context.CreateParameter("@authority", authorityString),
                Context.CreateParameter("@id", userId)
            });
        }

        public void AddRoles(int userId, int[] roleIdArray)
        {
            string sql = "insert into [userrole]([userid], [roleid]) values({0}, {1})";
            foreach (var item in roleIdArray)
            {
                sql = String.Format(sql, userId, item);
                Context.ExecuteNonQuery(sql);
            }
        }

        public void DeleteRoles(int userId, int[] roleIdArray)
        {
            string sql = "delete from [userrole] where [userid]={0} and [roleid]={1}";
            foreach (var item in roleIdArray)
            {
                sql = String.Format(sql, userId, item);
                Context.ExecuteNonQuery(sql);
            }
        }

        protected override User ReadEntityFromDataReader(IDataReader dr)
        {
            //return base.ReadEntityFromDataReader(dr);
            User user = new User()
            {
                Id = dr.Read<int>("id"),
                Mail = dr.Read<string>("mail"),
                Name = dr.Read<string>("name"),
                Password = dr.Read<string>("password"),
                Authorities = dr.Read<string>("authority").ToJsonObject<Authority[]>()
            };
            return user;
        }

        public void UpdateStatus(int userId, string LoginToken)
        {
            throw new NotImplementedException();
        }

        public void AddLoginStatus(LoginStatus loginStatus)
        {
            throw new NotImplementedException();
        }

        public void UpdateLoginStatus(LoginStatus loginStatus)
        {
            throw new NotImplementedException();
        }

        public void DeleteLoginStatus(string token)
        {
            throw new NotImplementedException();
        }

        public void DeleteAllLoginStatus(int userId)
        {
            throw new NotImplementedException();
        }

        public LoginStatus GetLoginStatus(string token)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<LoginStatus> GetLoginStatusList(int userId)
        {
            throw new NotImplementedException();
        }

        public void DeleteLoginStatus(int userId)
        {
            throw new NotImplementedException();
        }

        public OAuthUserBinding GetOAuthUserBinding(string blogUserId, string mark)
        {
            throw new NotImplementedException();
        }

        public void AddOAuthUserBinding(OAuthUserBinding microuser)
        {
            throw new NotImplementedException();
        }


        public OAuthUserBinding GetOAuthUserBindingSingle(string userIdentity, int authId)
        {
            throw new NotImplementedException();
        }


        public OAuthUserBinding GetOAuthUserBindingSingle(ISpecification<OAuthUserBinding> specification)
        {
            throw new NotImplementedException();
        }

        public void DeleteOAuthUserBinding(int id)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<OAuthUserBinding> GetOAuthUserBindingList(ISpecification<OAuthUserBinding> specification)
        {
            throw new NotImplementedException();
        }
    }
}
